#!/usr/bin/python2.5
# Copyright 2009 Joe LaPenna
"""Declare the datastore model."""

import datetime
import logging

from google.appengine.api import memcache
from google.appengine.ext import db


class User(db.Model):
  user = db.UserProperty(required=True)
  user_id = db.StringProperty(required=True)

  def get_products(self):
    """Get list of products by the current user."""
    logging.debug('user: %s', self)

    logging.debug('Finding Products')
    products = Product.all().order('name')

    logging.debug('Found: ' + str(products.count()))
    return products

  @staticmethod
  def find(appengine_user):
    """Find User provided a users.User (or return None)."""
    rows = User.gql('WHERE user_id = :user_id',
        user_id=appengine_user.user_id())
    for row in rows:
      logging.debug('Found existing User for %s', appengine_user)
      return row
    else:
      logging.debug('Unable to find User for %s', appengine_user)
      return None


class Product(db.Model):
  # key = the "productKey"
  user = db.ReferenceProperty(User, required=True)
  name = db.StringProperty(required=True)
  secret = db.StringProperty(required=True)
  tasks = db.StringListProperty()

  def get_crashes(self):
    """Get list of crashes by the chosen product."""
    logging.debug('Finding Crashes')
    crashes = db.GqlQuery(
        'SELECT * FROM Crash WHERE product = :1 ORDER BY date ASC', self)

    logging.debug('Found: ' + str(crashes.count()))
    return crashes

  @staticmethod
  def find(product_key):
    if product_key is None:
      return None

    # try and find it from the cache
    product = memcache.get('product-' + product_key)
    if product is not None:
      return product

    # Try and find it from the datastore
    product = db.get(product_key)
    if product is not None:
      # Cache the product and return
      logging.debug('Caching: product-' + product_key)
      memcache.add('product-' + product_key, product)
      return product


class Crash(db.Model):
  product = db.ReferenceProperty(Product, required=True)

  # unique identifier for a particular user/client/whatever.
  client = db.StringProperty()

  # When it happened according to the client. Defaults to request time.
  date = db.DateTimeProperty(auto_now_add=True)

  # For < 500 byte dumps - Searchable
  short = db.StringProperty()

  # For > 500 byte dumps - Not Searchable
  long = db.TextProperty()

  # For starters, lets allow one "tag"
  tag = db.StringProperty()

  # For starters, lets allow one severity
  severity = db.IntegerProperty()

  # For starters, lets allow a version string
  version = db.StringProperty()
